import { apiJavaUrl, apiUrl, apiUrl1 } from '@/config/config';
import { history } from '@/router';
import useUserStore from '@/store/user';
import { message as Message } from 'antd';
import { fileSave, supported } from 'browser-fs-access';
import saveAs from 'file-saver';
import createRequest from './createResquest';
import { CreateRequestConfig, ResultError } from './type';
import useRequest from './useRequest';

const MessageDuration = 2;
/**
 * 请求成功拦截器
 */
const successInterceptor: CreateRequestConfig['successInterceptor'] = (res, response, option) => {
  const { success, onSuccess, error, onError } = option;
  const { data: resData } = response;
  if (resData.newToken && resData.newToken !== '') {
    useUserStore.getState().setToken(resData.newToken);
  }
  if (resData.code === '200') {
    const result = resData.data;
    if (success) {
      let message = '';
      let duration = MessageDuration;
      if (typeof success === 'string') {
        message = success;
      } else {
        message = success.message;
        duration = success.duration || MessageDuration;
      }
      Message.success(message, duration);
    }
    res.data = result;
    res.ok = true;
    onSuccess && onSuccess(result, response);
  } else if (response.headers['content-type'] === 'application/vnd.ms-excel;charset=utf-8') {
    const disposition = response.headers['content-disposition'];
    let filename = '文件';
    if (disposition) {
      filename = disposition.split('filename=').pop();
    }
    try {
      if (supported) {
        fileSave(resData, {
          fileName: decodeURIComponent(filename),
          startIn: 'downloads',
          extensions: ['.xlsx']
        });
      } else {
        saveAs(resData, decodeURIComponent(filename));
      }
    } catch (error) {
      localStorage.setItem('error', JSON.stringify(error));
      saveAs(resData, decodeURIComponent(filename));
    }
  } else {
    // 用户级别错误
    res.ok = false;
    // eslint-disable-next-line prefer-const
    let { data, message } = resData;
    if (data) {
      message = data;
    }
    const err: ResultError = { message, name: 'user' };
    res.err = err;
    const errorMsg = message ?? '请求错误，请稍后再试';
    if (error) {
      if (error === true) {
        Message.error(errorMsg);
      } else if (error instanceof Function) {
        error(res.err);
      } else {
        let userMessage = '';
        let duration = MessageDuration;
        if (typeof error === 'string') {
          userMessage = error;
        } else {
          userMessage = error.message;
          duration = error.duration || MessageDuration;
        }
        Message.error(`${userMessage} ，${errorMsg}`, duration);
      }
    }
    onError && onError(err, response);
  }
  return res;
};

/**
 * 请求错误 message Map
 */
export const errorMessage: Record<number, string> = {
  500: '服务器内部错误，请联系管理员',
  400: '请求参数错误，请检查后重试',
  504: '网关错误，请稍后再试',
  404: '请求不存在，请联系管理员',
  403: '请求无权限，请联系管理员',
  401: '账号身份验证失败，请重新登录'
};

/**
 * 请求成功拦截器
 */
const errorInterceptor: CreateRequestConfig['errorInterceptor'] = (res, resError, option) => {
  const { error, onError } = option;
  const err: ResultError = { message: resError.message, name: 'system' };
  res.err = err;
  res.ok = false;
  // 展示error
  if (error !== false && error !== undefined) {
    if (error instanceof Function) {
      error(res.err);
    } else if (resError.message === 'Network Error') {
      Message.error('网络错误 ，请稍后再试');
    } else if (resError.code === 'ECONNABORTED' && resError.message.indexOf('timeout') !== -1) {
      Message.error('请求超时 ，请稍后再试');
    } else if (resError.response && resError.response.status in errorMessage) {
      Message.error(errorMessage[resError.response.status]);
      if (resError.response.status === 401) {
        const { pathname } = history.location;
        history.replace(`/logout?redirect=${pathname}`);
      }
    } else {
      Message.error(`请求失败，请稍后再试`);
    }
    onError && onError(err, resError);
  }
  return res;
};

/**
 * 默认请求
 */
const request = createRequest({
  baseURL: apiUrl,
  successInterceptor,
  errorInterceptor,
  timeout: 120000
});
/**
 * 默认请求, rpc for java
 */
const request_java = createRequest({
  baseURL: apiJavaUrl,
  successInterceptor,
  errorInterceptor,
  timeout: 120000
});
/**
 * 默认请求
 */
const request_1 = createRequest({
  baseURL: apiUrl1,
  successInterceptor,
  errorInterceptor,
  timeout: 120000
});
/**
 * mock请求
 */
const requestMock = createRequest({
  baseURL: '/api',
  successInterceptor,
  errorInterceptor
});
/**
 * xhr 文件请求
 */
const requestStatic = createRequest({});

export { requestMock, request, request_1, request_java, requestStatic, useRequest };
